import React, {
  useRef,
  useState,
  forwardRef,
  useMemo,
  useCallback,
  useEffect,
} from 'react'
import {
  EditableProTable,
  ActionType,
  TableDropdown,
} from '@ant-design/pro-table'
import { DnFC } from '@designable/react'
import {
  Space,
  Typography,
  Dropdown,
  Popconfirm,
  Button,
  Tag,
  Tabs,
} from 'antd'
import { useDialogInstances } from '@designable/react'
import ProTimeRangeSeparate from '../ProTimeRangeSeparate'
import { FormCascaderCategory } from '../FormCascaderCategory'
import createEvent, {
  CreateExecutor,
  goTo,
  dataSources,
  useT,
} from '@designable/event-system'
import { useForm } from '@formily/react'
import AccessBox from '../AccessBox'
import { DownOutlined } from '@ant-design/icons'
import * as AntdIcons from '@ant-design/icons'
import dayjs from 'dayjs'
// import { observer, useField } from '@formily/reactive-react'
import { useField, observer, connect, mapProps } from '@formily/react'
import DesensitizationBox from '../DesensitizationBox'
import { ProFormInstance } from '@ant-design/pro-form'

// 常量定义
const DEFAULT_SHOW_LEN = 3
const DEFAULT_ACTION_WIDTH = 200
const DEFAULT_PAGE_SIZE = 10
const DEFAULT_PAGE_SIZE_OPTIONS = ['10', '20', '50', '100']
const DEFAULT_SEARCH_STYLE = {
  background: '#F7F8FA',
  padding: '24px 20px',
  borderRadius: 4,
}

// 类型定义
interface ButtonItem {
  text: string
  type?: string
  disabled?: any
  dialog?: string
  visible?: any
  accessKey?: string
  usePopconfirm?: boolean
  popconfirmTitle?: string
  customExpression?: any
  buttonType?: 'default' | 'link' | 'text' | 'ghost' | 'primary' | 'dashed'
  size?: 'large' | 'middle' | 'small'
  icon?: string
}

interface ActionConfig {
  fixed?: boolean
  width?: number
  title?: string
  showLen?: number
}

interface RowSelectionConfig {
  enabled?: boolean
  type?: 'checkbox' | 'radio'
  fixed?: boolean
  columnWidth?: number
  columnTitle?: string
  preserveSelectedRowKeys?: boolean
  hideSelectAll?: boolean
  checkStrictly?: boolean
  onChange?: any
  getCheckboxProps?: any
  renderCell?: any
}

interface PaginationConfig {
  enabled?: boolean
  size?: 'default' | 'small'
  current?: number
  pageSize?: number
  defaultPageSize?: number
  showQuickJumper?: boolean
  showSizeChanger?: boolean
  position?:
    | 'topLeft'
    | 'topCenter'
    | 'topRight'
    | 'bottomLeft'
    | 'bottomCenter'
    | 'bottomRight'
  responsive?: boolean
  hideOnSinglePage?: boolean
  simple?: boolean
}

interface ProTableProps {
  rowKey?: string
  columns?: { data: any[] }
  action?: ActionConfig & { buttons?: { data: ButtonItem[] } }
  toolBarRender?: { data: ButtonItem[] }
  rowSelection?: RowSelectionConfig
  pagination?: PaginationConfig
  request?: any
  scroll?: { x?: number; y?: number }
  tabs?: any
  value?: any
  onChange?: (value: any) => void
}

// 工具函数
const safeExecute = (executor: any, context: any, fallback: any = null) => {
  try {
    return CreateExecutor(executor)(context)
  } catch (error) {
    console.error('执行表达式失败:', error)
    return fallback
  }
}

const getIconComponent = (iconName: string) => {
  return iconName && (AntdIcons as Record<string, any>)[iconName]
}

export const ProTable: DnFC<ProTableProps> = observer((props) => {
  const $t = useMemo(() => useT(), [])
  const { rowKey, tabs: expressionTabs } = props
  const isRequest = Boolean(props.request)
  const value = props.value || []
  const form = useForm()
  const actionRef = useRef<ActionType>()
  const formRef = useRef<ProFormInstance>()
  const [selectedRows, setSelectedRows] = useState([])
  const [selectedRowKeys, setSelectedRowKeys] = useState([])
  const dialogInstances = useDialogInstances()
  const [tabsItems, setTabsItems] = useState<any[]>([])
  const [tabActiveKey, setTabActiveKey] = useState('')

  useEffect(() => {
    if (!$t) return
    if (expressionTabs) {
      Promise.resolve(
        createEvent(expressionTabs, {
          actionRef: actionRef.current,
          form,
          $t,
        })
      ).then((res: any) => {
        setTabsItems(Array.isArray(res) ? res : [])
      })
    }
  }, [expressionTabs, form, $t])

  useEffect(() => {
    if (!tabActiveKey && tabsItems[0]?.value) {
      setTabActiveKey(tabsItems[0].value)
    }
  }, [tabsItems, tabActiveKey])

  // 处理行选择变化
  const handleRowSelectionChange = useCallback(
    (selectedKeys: any[], selectedRows: any[]) => {
      setSelectedRowKeys(selectedKeys)
      setSelectedRows(selectedRows)

      // 如果配置了自定义的 onChange 回调，则执行
      if (props.rowSelection?.onChange) {
        safeExecute(props.rowSelection.onChange, {
          selectedRowKeys: selectedKeys,
          selectedRows: selectedRows,
          form,
          actionRef: actionRef.current,
        })
      }
    },
    [props.rowSelection?.onChange, form]
  )

  // 处理按钮点击事件
  const handleButtonAction = useCallback(
    (item: ButtonItem, record?: any) => {
      const context = {
        form,
        actionRef: actionRef.current,
        formRef: formRef.current,
        selectedRows,
        selectedRowKeys,
        $t,
      }
      // 打开对话框
      if (item.dialog) {
        ;(dialogInstances.get(item.dialog) as any)?.open({
          ...context,
          record,
        })
      }
      // 执行自定义表达式
      if (item.customExpression) {
        createEvent(item.customExpression, { ...context, record })
      }
    },
    [form, selectedRows, selectedRowKeys, $t, dialogInstances]
  )

  // 渲染网络管理下拉菜单
  const renderNetworkDropdown = useCallback(
    (item: ButtonItem, record: any, index?: number) => {
      const categoryProjectInfos = record.categoryProjectInfos || []
      const equityCode = record.equityCode || record.equityGetResp.equityCode

      if (categoryProjectInfos.length > 1) {
        return (
          <AccessBox key={index} accessKey={item.accessKey || ''}>
            <Dropdown
              menu={{
                items: categoryProjectInfos.map((category: any) => ({
                  key: category.projectId,
                  label: (
                    <Typography.Link
                      onClick={() =>
                        goTo(
                          `/commodity/networkMgmt/equity?equityCode=${equityCode}&projectId=${category.projectId}&categoryType=${category.categoryType}&lastSubType=${category.lastSubType}`
                        )
                      }
                    >
                      {category.categoryTypeName}
                    </Typography.Link>
                  ),
                })),
              }}
            >
              <Typography.Link>
                <Space>
                  {$t('查看网点')}
                  <DownOutlined />
                </Space>
              </Typography.Link>
            </Dropdown>
          </AccessBox>
        )
      }
      const { projectId, categoryType, lastSubType } = record
      return (
        <AccessBox key={index} accessKey={item.accessKey || ''}>
          <Typography.Link
            onClick={() =>
              goTo(
                `/commodity/networkMgmt/equity?equityCode=${equityCode}&projectId=${projectId}&categoryType=${categoryType}&lastSubType=${lastSubType}`
              )
            }
          >
            {$t('查看网点')}
          </Typography.Link>
        </AccessBox>
      )
    },
    []
  )

  // 渲染操作按钮
  const renderActionButton = useCallback(
    (item: ButtonItem, record: any, index?: number) => {
      // 检查可见性
      if (item.visible && !safeExecute(item.visible, record, true)) {
        return null
      }

      // 检查禁用状态
      const disabled = item.disabled
        ? safeExecute(item.disabled, record, false)
        : false

      // 特殊类型按钮处理
      if (item.type === 'networkDropdown') {
        return renderNetworkDropdown(item, record, index)
      }

      const onAction = () => handleButtonAction(item, record)

      const linkEl = (
        <Typography.Link
          disabled={disabled}
          onClick={!item.usePopconfirm ? onAction : undefined}
        >
          {$t(item.text)}
        </Typography.Link>
      )

      const buttonElement = (
        <AccessBox key={index} accessKey={item.accessKey || ''}>
          {item.usePopconfirm ? (
            <Popconfirm
              disabled={disabled}
              title={item.popconfirmTitle || $t('确定要执行该操作吗？')}
              onConfirm={onAction}
            >
              <span>{linkEl}</span>
            </Popconfirm>
          ) : (
            linkEl
          )}
        </AccessBox>
      )

      return buttonElement
    },
    [renderNetworkDropdown, handleButtonAction]
  )

  // 渲染下拉菜单项
  const renderDropdownItem = useCallback(
    (item: ButtonItem, record: any, index: number) => {
      // 检查可见性
      if (item.visible && !safeExecute(item.visible, record, true)) {
        return null
      }

      // 检查禁用状态
      const disabled = item.disabled
        ? safeExecute(item.disabled, record, false)
        : false

      return {
        key: `${index}`,
        name: (
          <AccessBox accessKey={item.accessKey || ''}>
            <Typography.Link disabled={disabled}>
              {$t(item.text)}
            </Typography.Link>
          </AccessBox>
        ),
        label: (
          <AccessBox accessKey={item.accessKey || ''}>
            <Typography.Link disabled={disabled}>
              {$t(item.text)}
            </Typography.Link>
          </AccessBox>
        ),
        onClick: () => handleButtonAction(item, record),
        disabled,
      }
    },
    [$t, handleButtonAction]
  )

  // 渲染操作列
  const renderActionColumn = useCallback(
    (buttons: ButtonItem[], action: ActionConfig, record: any) => {
      const showLen = action.showLen ?? DEFAULT_SHOW_LEN

      // 过滤可见按钮
      const visibleButtons = buttons.filter((item: ButtonItem) => {
        if (!item.visible) return true
        return safeExecute(item.visible, record, true)
      })

      // 如果按钮数量不超过showLen，直接显示所有按钮
      if (visibleButtons.length <= showLen) {
        return (
          <Space>
            {visibleButtons.map((item: ButtonItem, index: number) =>
              renderActionButton(item, record, index)
            )}
          </Space>
        )
      }

      // 如果按钮数量超过showLen，分为显示的按钮和下拉菜单中的按钮
      const displayButtons = visibleButtons.slice(0, showLen - 1)
      const dropdownButtons = visibleButtons.slice(showLen - 1)

      const dropdownItems = dropdownButtons
        .map((item: ButtonItem, index: number) =>
          renderDropdownItem(item, record, index + showLen - 1)
        )
        .filter(Boolean)

      return (
        <Space>
          {displayButtons.map((item: ButtonItem, index: number) =>
            renderActionButton(item, record, index)
          )}
          {dropdownItems.length > 0 && (
            <AccessBox accessKey="">
              <TableDropdown menus={dropdownItems} />
            </AccessBox>
          )}
        </Space>
      )
    },
    [renderActionButton, renderDropdownItem]
  )

  // 处理列配置
  const columns = useMemo(() => {
    const baseColumns = (props.columns?.data || []).map((item: any) => {
      let render
      if (item.desensitize) {
        render = (text: any, record: any) => {
          return <DesensitizationBox data={record[item.dataIndex]} />
        }
      }
      if (item.isRender) {
        render = (text: any, record: any) => {
          return safeExecute(item.render, {
            record,
            $t,
          })
        }
      }

      let renderFormItem
      if (item.renderFormItem === 'select') {
        item.valueType = 'select'
        if (item.selectRequest) {
          item.request = async (keywords: any) => {
            const data = await dataSources[item.selectRequest]?.($t, keywords)
            return data
          }
        }
        if (!item.selectRequest && item.requestExpression) {
          item.request = async (keywords: any) => {
            return await createEvent(item.requestExpression, {
              keywords,
              $t,
            })
          }
        }
      }
      if (item.search) {
        if (item.renderFormItem === 'rangePicker') {
          if (item.initialValueMonth) {
            const startValue = dayjs().subtract(1, 'month').format('YYYY-MM-DD')
            const endValue = dayjs().format('YYYY-MM-DD')
            renderFormItem = () => (
              <ProTimeRangeSeparate
                startTimeName={item.rangStartName}
                endTimeName={item.rangEndName}
                initialValue={[startValue, endValue]}
              />
            )
          } else {
            renderFormItem = () => (
              <ProTimeRangeSeparate
                startTimeName={item.rangStartName}
                endTimeName={item.rangEndName}
              />
            )
          }
        }
        if (item.renderFormItem === 'categoryPicker') {
          renderFormItem = () => <FormCascaderCategory />
          render = (text: any, record: any) => {
            return record.subTypeName
              ? `${record.categoryTypeName} / ${record.subTypeName}`
              : record.categoryTypeName
          }
        }
      }
      if (item.tag) {
        render = (text, record) => {
          return record.tagColor ? (
            <Tag color={record.tagColor}>{record[item.dataIndex]}</Tag>
          ) : (
            <Tag>{record[item.dataIndex]}</Tag>
          )
        }
      }

      const { initialValue, ...restItem } = item
      return {
        ...restItem,
        ellipsis: restItem.ellipsis !== false,
        render,
        renderFormItem,
        title: $t(item.title),
        search: Boolean(item.search),
        dataIndex: item.dataIndex ? item.dataIndex.split('.') : 'dataIndex',
      }
    })

    // 添加操作列
    const { buttons, ...action } = props.action || {}
    if (
      buttons?.data &&
      Array.isArray(buttons.data) &&
      buttons.data.length > 0
    ) {
      baseColumns.push({
        fixed: action.fixed || false,
        width: action.width || DEFAULT_ACTION_WIDTH,
        title: action.title ? $t(action.title) : '',
        valueType: 'option',
        key: 'option',
        render: (_text: any, record: any) =>
          renderActionColumn(buttons.data, action, record),
      })
    }
    return baseColumns
  }, [props.columns?.data, props.action, $t, renderActionColumn])

  // 检查是否有搜索功能
  const hasSearch = useMemo(
    () => Array.isArray(columns) && columns.some((col: any) => col?.search),
    [columns]
  )

  // 渲染工具栏按钮
  const renderToolbarButtons = useCallback(() => {
    const items = props.toolBarRender?.data
    if ((!Array.isArray(items) || items.length === 0) && !tabsItems.length)
      return []

    const visibleButtons = items.filter((item: ButtonItem) => {
      if (!item.visible) return true
      return safeExecute(item.visible, {}, true)
    })

    const buttons = visibleButtons.map((item: ButtonItem, index: number) => {
      const disabled = item.disabled
        ? safeExecute(
            item.disabled,
            {
              form,
              actionRef: actionRef.current,
              formRef: formRef.current,
              selectedRows,
              selectedRowKeys,
              $t,
            },
            false
          )
        : false

      const onAction = () => handleButtonAction(item)

      const IconCmp = getIconComponent(item.icon)
      const btn = (
        <AccessBox key={index} accessKey={item.accessKey || ''}>
          <Button
            type={item.buttonType || 'default'}
            size={item.size}
            disabled={disabled}
            onClick={!item.usePopconfirm ? onAction : undefined}
            icon={IconCmp ? <IconCmp /> : null}
          >
            {$t(item.text)}
          </Button>
        </AccessBox>
      )

      if (item.usePopconfirm) {
        return (
          <Popconfirm
            key={index}
            disabled={disabled}
            title={
              item.popconfirmTitle
                ? $t(item.popconfirmTitle)
                : $t('确定要执行该操作吗？')
            }
            onConfirm={onAction}
          >
            <span>{btn}</span>
          </Popconfirm>
        )
      }

      return btn
    })

    const btnLen = buttons.length

    return [
      <div className="tool-bar-render" key="tool">
        {btnLen > 0 ? <Space>{buttons}</Space> : null}
        {tabsItems.length > 0 ? (
          <div
            className="tool-bar-hanlde"
            style={{ marginTop: btnLen > 0 ? '34px' : '0' }}
          >
            <Tabs
              activeKey={tabActiveKey}
              onChange={(e: any) => {
                setTabActiveKey(e)
                actionRef.current?.reloadAndRest()
              }}
            >
              {tabsItems.map((v: any) => (
                <Tabs.TabPane tab={v.label} key={v.value}></Tabs.TabPane>
              ))}
            </Tabs>
          </div>
        ) : null}
      </div>,
    ]
  }, [
    props.toolBarRender?.data,
    form,
    selectedRows,
    selectedRowKeys,
    $t,
    handleButtonAction,
    tabActiveKey,
    tabsItems,
  ])

  // 处理请求函数
  const handleRequest = useCallback(
    async ({ pageSize, ...params }: any) => {
      if (!props.request) {
        return {
          data: [],
          success: false,
          total: 0,
        }
      }
      try {
        const res = await createEvent(props.request, {
          actionRef: actionRef.current,
          form,
          params: {
            ...params,
            tabActiveKey: tabsItems.length > 0 ? tabActiveKey : undefined,
            size: pageSize,
          },
        })
        if (Array.isArray(res)) {
          return {
            data: res,
            success: true,
            total: res.length,
          }
        }
        return {
          data: res.records,
          success: true,
          total: res.total,
        }
      } catch (error) {
        console.error('请求数据失败:', error)
        return {
          data: [],
          success: false,
          total: 0,
        }
      }
    },
    [props.request, form, tabActiveKey]
  )

  // 行选择配置
  const rowSelectionConfig = useMemo(() => {
    if (!props.rowSelection?.enabled) return false

    const config: any = {
      selectedRowKeys,
      onChange: handleRowSelectionChange,
      type: props.rowSelection.type || 'checkbox',
      fixed: props.rowSelection.fixed || false,
      columnWidth: props.rowSelection.columnWidth || 60,
      columnTitle: props.rowSelection.columnTitle,
      preserveSelectedRowKeys:
        props.rowSelection.preserveSelectedRowKeys || false,
      hideSelectAll: props.rowSelection.hideSelectAll || false,
      checkStrictly: props.rowSelection.checkStrictly || false,
    }

    if (props.rowSelection.getCheckboxProps) {
      config.getCheckboxProps = (record: any) =>
        safeExecute(props.rowSelection.getCheckboxProps, record, {})
    }

    if (props.rowSelection.renderCell) {
      config.renderCell = (checked: boolean, record: any) =>
        safeExecute(props.rowSelection.renderCell, { checked, record }, null)
    }

    return config
  }, [props.rowSelection, selectedRowKeys, handleRowSelectionChange])

  // 分页配置
  const paginationConfig = useMemo(() => {
    if (props.pagination?.enabled === false) return false

    return {
      size: props.pagination?.size || 'default',
      defaultCurrent: props.pagination?.current || 1,
      defaultPageSize: props.pagination?.defaultPageSize || DEFAULT_PAGE_SIZE,
      showQuickJumper: props.pagination?.showQuickJumper !== false,
      showSizeChanger: props.pagination?.showSizeChanger !== false,
      pageSizeOptions: DEFAULT_PAGE_SIZE_OPTIONS,
      position: [props.pagination?.position || 'bottomRight'],
      responsive: props.pagination?.responsive !== false,
      hideOnSinglePage: props.pagination?.hideOnSinglePage || false,
      simple: props.pagination?.simple || false,
    }
  }, [props.pagination])

  // 搜索配置
  const searchConfig = useMemo(() => {
    if (!hasSearch) return false

    return {
      labelWidth: 'auto' as const,
      collapsed: false,
      collapseRender: () => <></>,
      style: DEFAULT_SEARCH_STYLE,
    }
  }, [hasSearch])

  const scrollConfig = useMemo(() => {
    return {
      x: props.scroll?.x,
      y: props.scroll?.y,
    }
  }, [props.scroll])

  return (
    <EditableProTable
      actionRef={actionRef}
      formRef={formRef}
      rowKey={rowKey || 'id'}
      columns={columns}
      recordCreatorProps={false}
      value={isRequest ? undefined : value}
      request={handleRequest}
      toolBarRender={renderToolbarButtons}
      search={searchConfig}
      rowSelection={rowSelectionConfig}
      pagination={paginationConfig}
      scroll={scrollConfig}
    />
  )
})
